/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *EJERCICIO 2
 * 
 * CLASE PARA OBJETOS de Lista
 * MANEJA LOS NODOS
 * VICTOR FUENTES 12298
 * MARCOS LOPEZ 12519
 * YUCELY BEB 12537
 * 
 */
package hoja.de.trabajo;


public  class Lista implements iPila{
    //atributos de la lista 
    int count;
    NodoLista cabeza;
    
    public Lista(){
        cabeza=null;
        count=0;
    }
    //tamaño de la lista, o sea el contador
    public int getTamano(){
        return count;
    }
    
    //metodo para agregar elementos al inicio
    public void agregarInicio(String in){
        cabeza=new NodoLista();//se aceptan el valor y el puntero
        cabeza.setValor(in);//al nuevo objeto llamado cabeza sera la nueva cabeza
        cabeza.SetPuntero(cabeza);
        count++;
    }
    
    
    //metodo para remover el primero
    public String quitarPrimero(){
       NodoLista temp=cabeza;//el actual cabeza se almacena temporal para quitarlo
       cabeza=cabeza.Siguiente();//realizo un nuevo puntero eliminado el primero
       //ahora la nueva cabeza tiene el segundo puntero, o sea el primero que es ahora
       
       count--;//conteo de elementos disminuy porque elimine de la lista
       return temp.getValor();
    }
    
    //devuelve el primer elemento de la lista
    public String getPrimero(){
        return cabeza.getValor();
    }
    
    //metodo para agregar elementos a la lista
    public void push(String nuevovalor){
        NodoLista temp=new NodoLista();
        temp.setValor(nuevovalor);//crear objeto temporal con puntero=null, 
        temp.SetPuntero(null);  //pero con valor ingresado desde el usuario
        if(cabeza!=null){
            NodoLista finger=cabeza;//PUNTERO de busqueda en la lista
            while(finger.Siguiente()!=null){//si este puntero no es null, 
                                            //entonces avanzo para conseguir el final
                finger=finger.Siguiente();
            }
            finger.SetPuntero(temp);
        }else 
        {
            cabeza=temp;
        }//como se fue al final y era cabeza, entonces se 
                        //ingresa a cabeza el objeto temporan que recibio
                          // el valor de entrada
        count++;//actualiza contador de general de cabeza
    }
    //metod para mostrar el ultimo elemento de la pila
    public String getUltimo(){
        NodoLista finger=cabeza;
        NodoLista anterior=null;
        //Assert.pre(cabeza!=null, "lista vacia");
        
        while(finger.Siguiente()!=null){//mientras no sea puntero null
            anterior=finger;//uso el anterior para referirme al anterior
            finger=finger.Siguiente();//actualizo el puntero de finger al 
                                        //siguiente elemento
            
        }
        //si llega aqui, entonces el puntero es nulo
        //entonces es final de lista o null
        if(anterior==null){
            //cabeza=null;//solo esta un elemento
        }else{
            //anterior.SetPuntero(null);//entonces anterior es nulo
        }
        //count--; modificacion para que no quiete el ultimo elemento, solo mostrarlo
        return finger.getValor();//retorno el valor que quito para control
        
    }
    
    
    //metodo para quitar al final
    public String pop(){
        NodoLista finger=cabeza;
        NodoLista anterior=null;
        //Assert.pre(cabeza!=null, "lista vacia");
        //if(cabeza!=null) System.out.println("lista vacia");
        while(finger.Siguiente()!=null){//mientras no sea puntero null
            anterior=finger;//uso el anterior para referirme al anterior
            finger=finger.Siguiente();//actualizo el puntero de finger al 
                                        //siguiente elemento
            
        }
        //si llega aqui, entonces el puneto es nulo
        //entonces es final de lista o null
        if(anterior==null){
            cabeza=null;//solo esta un elemento
        }else{
            anterior.SetPuntero(null);//entonces anterior es nulo
        }
        count--;
        return finger.getValor();//retorno el valor que quito para control
    }
    
    //metodo para verificar si elemento esta en lista
    public boolean hayElementos(String prueba){
        NodoLista finger=cabeza;
        //while que valida mientras finger no sea nulo y el valor de finger
        //no sea igual asi mismo
        while(finger!=null && !finger.getValor().equals(prueba)){
            finger=finger.Siguiente();
        }
        return finger!=null;//cuando se llega a encontrar un valor hay true si 
                        //mismo elemento en lista que el ingresado en prueba
    }
    
    //metodo para remover un valor segun sea igual al prompt
    public String removerSegunStr(String prueba){
        NodoLista finger=cabeza;
        NodoLista anterior=null;
        //si finger/cabeza no es nulo y el valor de finger/cabeza no es igual a 
        //valor ingresado en prueba, se sigue con el while
        while(finger!=null && !finger.getValor().equals(prueba)){
            anterior=finger;
            finger=finger.Siguiente();//se actualiza el finger para que 
                                    //apunte al siguiente
        }
        
        //finger ya encontro un objeto que es igual al prueba, 
        //o sea un objeto con el mismo String al ingresado en prueba
        if(finger!=null){//finger no es nulo
           
            if(anterior==null){//si anterior es nulo, entonces es 1er elemento
                cabeza=finger.Siguiente();//finger apunta a cabeza
            }else{//no es primer elemento
                anterior.SetPuntero(finger.Siguiente());
                //anterior debe de apuntar a los que finger apuntaba
            }
            count--;
            return finger.getValor();//retorno el valor que si coincide
        }
        return null;//como no hay coincidencia se retorna nulo
    }
    
    
    
    //metodo para reiniciar la lista, o sea borrala
    public void limpiar(){
        cabeza=null;
        count=0;
    }
    
    //metodo para agregar en una posicion y un valor tipo string<>
    public void agregar(int i, String o){
       if(i<=getTamano() && i>=0){//validar de que i en rango valido
           System.out.println("Indice esta en rango.");
       }
       
       if(i==getTamano()){//si i iguala a tamaña, entonces es ultimo
           push(o);
       }else if(i==0){//si i iguala a inicio
           agregarInicio(o);
       }else{//si i se encuentra  a la mitad buscarlo
           NodoLista anterior=null;
           NodoLista finger=cabeza;
           while(i>0){//se busca que el finger apunte a objeto segun el contador
                    //i que se va disminuiyendo, o sea cuento cuantos objetos
                      //llevo referenciado para detectar cual debo de modificar
               anterior=finger;
               finger=finger.Siguiente();
               i--;
           }
           //se crea en el nuevo objeto que se ingresa en la lista
           NodoLista actual=new NodoLista();
           actual.setValor(o);
           actual.SetPuntero(finger);//se crea el nuevo objeto nodo con 
                                    //parametros dados
           count++;//actualizo contador de la lista porque ingrese elemento
           anterior.SetPuntero(actual);//el objeto anterior debe de apuntar
                                //a este para que la lista no se rompa
       }
    
         
    }
    
    //metod opara remover segun indice dado
    public String removerSegunIndice(int i){
        if(i<=getTamano() && i>=0){//validar de que i en rango valido
           System.out.println("Indice esta en rango.");
        }
        
        //si indice es 0, es al inicio
        if (i==0){
            return quitarPrimero();//llamo a metodo para quitar primero
        }else if(i == getTamano()-1){//si es ultima posicion
            return pop();//llamo a metodo para quitar ultimo
        }else{//buscar en lista segun indice
            NodoLista anterior=null;
            NodoLista finger=cabeza;
            while(i>0){
                anterior = finger;
                finger=finger.Siguiente();
                i--;
            }
            //al terminar de encontar el objeto
            anterior.SetPuntero(finger.Siguiente());//anterior apunta a lo que
                                        //tenia finger y su puntero para
                                       //no cortar la lista
            count--;
            return finger.getValor();//regreso el valor que quite para control
        }
        
    }
    
    //metodo para imprimir lista
    public String imprimir(){
        String str="";
        NodoLista finger=cabeza;
        for(int i=0;i<getTamano();i++){
            str+=finger.getValor();
            finger=finger.Siguiente();
            
        }
        
        
        return str;
    }
    
    
}





